#include "i2c_driver.h"

#include  "esp_err.h"
#include "driver/i2c.h"




#include <stdio.h>
#include "esp_log.h"
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/queue.h"
#include "esp_sleep.h"
#include "driver/rtc_io.h"
#include "driver/i2c_master.h"
#define OLD_DRIVER_ENABLE 1





static uint8_t i2c_addr = 0x00;

static const char *TAG = "i2c-example";

#define DATA_LENGTH 512                  /*!< Data buffer length of test buffer */
#define RW_TEST_LENGTH 128               /*!< Data length for r/w test, [0,DATA_LENGTH] */
#define DELAY_TIME_BETWEEN_ITEMS_MS 1000 /*!< delay time between different test items */

#define I2C_SLAVE_SCL_IO CONFIG_I2C_SLAVE_SCL               /*!< gpio number for i2c slave clock */
#define I2C_SLAVE_SDA_IO CONFIG_I2C_SLAVE_SDA               /*!< gpio number for i2c slave data */

#define I2C_SLAVE_TX_BUF_LEN (2 * DATA_LENGTH)              /*!< I2C slave tx buffer size */
#define I2C_SLAVE_RX_BUF_LEN (2 * DATA_LENGTH)              /*!< I2C slave rx buffer size */

#define I2C_MASTER_SCL_IO CONFIG_I2C_MASTER_SCL               /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO CONFIG_I2C_MASTER_SDA               /*!< gpio number for I2C master data  */

#define I2C_MASTER_FREQ_HZ 200000                             /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0                           /*!< I2C master doesn't need buffer */


// #define ESP_SLAVE_ADDR 0x27//0x20 /*!< ESP32 slave address, you can set any 7bit value */
// #define TOF_SLAVE_ADDR 0x29 /*!< TOF slave address, you can set any 7bit value */
#define WRITE_BIT I2C_MASTER_WRITE              /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ                /*!< I2C master read */
#define ACK_CHECK_EN 0x1                        /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0                       /*!< I2C master will not check ack from slave */
#define ACK_VAL (i2c_ack_type_t)0x0                             /*!< I2C ack value */
#define NACK_VAL (i2c_ack_type_t)0x1                            /*!< I2C nack value */



esp_err_t i2c_master_write_slave(i2c_port_t i2c_num, uint8_t *data_wr, size_t size);
 esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, size_t size);


void i2c_driver_init(uint8_t scl_pin,uint8_t sda_pin){

    esp_err_t state;
    int i2c_master_port = I2C_MASTER_NUM;
    static i2c_config_t conf;
    conf.mode = I2C_MODE_MASTER;
    conf.sda_io_num = sda_pin;
    conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
    conf.scl_io_num = scl_pin;
    conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
    conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
    i2c_param_config(I2C_MASTER_NUM, &conf);
    state = i2c_driver_install(I2C_MASTER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);

    i2c_scan();

    
}








/**
 * @brief test code to read esp-i2c-slave
 *        We need to fill the buffer of esp slave device, then master can read them out.
 *
 * _______________________________________________________________________________________
 * | start | slave_addr + rd_bit +ack | read n-1 bytes + ack | read 1 byte + nack | stop |
 * --------|--------------------------|----------------------|--------------------|------|
 *
 */
 esp_err_t i2c_master_read_slave(i2c_port_t i2c_num, uint8_t *data_rd, size_t size)
{
    if (size == 0) {
        return ESP_OK;
    }
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (i2c_addr << 1) | READ_BIT, ACK_CHECK_EN);
    if (size > 1) {
        i2c_master_read(cmd, data_rd, size - 1, ACK_VAL);
    }
    i2c_master_read_byte(cmd, data_rd + size - 1, NACK_VAL);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);

    if (ret == ESP_OK) {
        //printf("I2C Transmission Success\n");
    } else if (ret == ESP_ERR_TIMEOUT) {
        printf("I2C Bus is busy, transmission timeout\n");
    } else {
        printf("I2C Transmission Failed, error: %d\n", ret);
    }


    i2c_cmd_link_delete(cmd);
    return ret;
}



 esp_err_t i2c_master_write_slave(i2c_port_t i2c_num, uint8_t *data_wr, size_t size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, (i2c_addr << 1) | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write(cmd, data_wr, size, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(i2c_num, cmd, 1000 / portTICK_PERIOD_MS);

    if (ret == ESP_OK) {
        //printf("I2C Transmission Success\n");
    } else if (ret == ESP_ERR_TIMEOUT) {
        printf("I2C Bus is busy, transmission timeout\n");
    } else {
        printf("I2C Transmission Failed, error: %d\n", ret);
    }

    i2c_cmd_link_delete(cmd);
    return ret;
}


// void pcf8574_i2c_read(uint8_t *data_rd, int size){

//     //SAL::take_i2c_lock();
//     i2c_master_read_slave(I2C_MASTER_NUM,data_rd, size);
//     //SAL::give_i2c_lock();
// }


// void pcf8574_i2c_write(uint8_t *data_wr, int size){
//     //SAL::take_i2c_lock();
//     i2c_master_write_slave(I2C_MASTER_NUM,data_wr, size);
//     //SAL::give_i2c_lock();
// }








// 写入
void driver_i2c_write(uint8_t reg, uint8_t data) {

  
    esp_err_t ret;
    uint8_t buf[2] = {reg, data};
    //SAL::take_i2c_lock();
    ret = i2c_master_write_to_device(I2C_NUM_0,i2c_addr, buf, sizeof(buf), 1000 / portTICK_PERIOD_MS);
    if (ret == ESP_OK) {
        //printf("I2C Transmission Success\n");
    } else if (ret == ESP_ERR_TIMEOUT) {
        printf("TCA9555 Write I2C Bus is busy, transmission timeout\n");
    } else {
        printf("TCA9555 Write I2C Transmission Failed, error: %d\n", ret);
    }
  

   
}

// 读取
void driver_i2c_read(uint8_t reg, uint8_t *data) {

  
    esp_err_t ret;
    ret = i2c_master_write_read_device(I2C_NUM_0,i2c_addr, &reg, 1, data, 1, 1000 / portTICK_PERIOD_MS);
    if (ret == ESP_OK) {
        //printf("I2C Transmission Success\n");
    } else if (ret == ESP_ERR_TIMEOUT) {
        printf("TCA9555 Read I2C Bus is busy, transmission timeout\n");
    } else {
        printf("TCA9555 Read I2C Transmission Failed, error: %d\n", ret);
    }
}



/*********************************************************************************
* function   :   i2c_scan     
* Description :  i2c �?描地址
* Input       :  
* Output      :  
* Author      :                    Data : 2024 09.30
**********************************************************************************/
void i2c_scan() {

    uint8_t data[1] = {0}; // 创建一�?有效的空数据数组
    esp_err_t esp_err;
    printf("I2C Scanner\n");

    for (uint8_t address = 1; address < 127; address++) {
        // 向地址发送数�?以�?�查�?��?�是否存�?
        esp_err = i2c_master_write_to_device(I2C_MASTER_NUM, address, data, sizeof(data), 10 / portTICK_PERIOD_MS);
        if (esp_err == ESP_OK) {
            
             printf("Found I2C device at address 0x%02X\n", address);

             i2c_addr = address;
           
        } else if (esp_err == ESP_ERR_INVALID_ARG) {
            // 地址无效，忽�?
            printf("i2c esp_err %d\r\n",esp_err);
            continue;
        }
    }
       //printf("I2C Scanner End %d\r\n",expand_chip_dev.expand_chip_slave_addr);
}


